#      t.integer :logged_ip_address_id
#      t.integer :logged_session_id
#      t.integer :logged_action_id
#      t.text :params
#      t.datetime :accessed_at
#      t.string :http_method
#      t.decimal :completion_time_in_secs
#      t.decimal :render_time_in_secs
#      t.decimal :db_time_in_secs
#      t.integer :http_status

class LogEntry < ActiveRecord::Base
	belongs_to :logged_ip_address
	belongs_to :logged_session
	belongs_to :logged_action
	
	serialize :params, Hash
	
	class << self
		def count_by_logged_controller_id(logged_controller_id)
			begin
				logged_controller = LoggedController.find logged_controller_id
				logged_action_ids = logged_controller.logged_actions.map(&:id)
				count :conditions => ["logged_action_id IN (?)", logged_action_ids ]
			rescue ActiveRecord::RecordNotFound
				0
			end
		end
		
		def count_by_logged_action_id(logged_action_id)
			count :conditions => ["logged_action_id = ?", logged_action_id ]
		end

    def times_for_controller_id(controller_id)
      @times_for_controllers ||= {}
      return @times_for_controllers[controller_id] unless @times_for_controllers[controller_id].nil?
      
      entries = find :all, :select => "log_entries.completion_time_in_secs, log_entries.render_time_in_secs, " +
        "log_entries.db_time_in_secs",
        :joins => "LEFT OUTER JOIN logged_actions ON logged_actions.id = log_entries.logged_action_id",
        :conditions => ["logged_actions.logged_controller_id = ?", controller_id]
      @times_for_controllers[controller_id] = { 
        :max_completion => entries.map(&:completion_time_in_secs).map(&:to_f).max,
        :min_completion => entries.map(&:completion_time_in_secs).map(&:to_f).min,
        :avg_completion => entries.map(&:completion_time_in_secs).map(&:to_f).average,
        :render     => entries.map(&:render_time_in_secs).map(&:to_f).average,
        :db         => entries.map(&:db_time_in_secs).map(&:to_f).average
      }
    end
    
    def average_times_for_action_id(action_id)
      @times_for_actions ||= {}
      return @times_for_actions[action_id] unless @times_for_actions[action_id].nil?
      
      entries = find :all, :select => "log_entries.completion_time_in_secs, log_entries.render_time_in_secs, " +
        "log_entries.db_time_in_secs",
        :conditions => ["logged_action_id = ?", action_id]
      @times_for_actions[action_id] = { 
        :completion => entries.map(&:completion_time_in_secs).map(&:to_f).average,
        :render     => entries.map(&:render_time_in_secs).map(&:to_f).average,
        :db         => entries.map(&:db_time_in_secs).map(&:to_f).average
      }
    end
    
    		
		# FIXME set up bind variables on find to search through a bunch of params
		def find_by_action_name_and_params(action_id, params)
			find :all, :include => :logged_action, :conditions => ["logged_actions.id = ? AND params LIKE ?", action_id]
		end
		
		# gives log entries for a single action, grouped by identical params (with count_by_params)
		def find_for_action_and_group_by_params(logged_action_id = nil)
			if logged_action_id
				find_by_sql [	"SELECT log_entries.*, count(*) as count_by_params, logged_actions.name as action_name from log_entries " +
											"LEFT OUTER JOIN logged_actions ON logged_actions.id = log_entries.logged_action_id " +
											"WHERE logged_action_id = ? GROUP BY params", logged_action_id]
			else
				find_by_sql 	"SELECT log_entries.*, count(*) as count_by_params, logged_actions.name as action_name from log_entries " +
											"LEFT OUTER JOIN logged_actions ON logged_actions.id = log_entries.logged_action_id " +
											"GROUP BY logged_action_id, params"
			end
		end
	end
	
	# used when using find with group by params
	def count_by_params
		attributes["count_by_params"].to_i
	end
	
	def action_name
		@action_name ||= (attributes["action_name"] || logged_action.name)
	end
end
